package com.googlecode.continuity.plugin.codecomment.server.rpc;

import java.util.Date;
import java.util.List;

import org.acegisecurity.context.SecurityContextHolder;
import com.googlecode.continuity.core.client.Reply;
import com.googlecode.continuity.core.server.security.SecurityUserToken;
import com.googlecode.continuity.plugin.codecomment.client.CodeComment;
import com.googlecode.continuity.plugin.codecomment.client.CodeCommentRPC;
import com.googlecode.continuity.plugin.codecomment.client.CodePointer;
import com.googlecode.continuity.plugin.codecomment.server.service.CodeCommentService;

/**
 * CodeCommentRPCImpl
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public class CodeCommentRPCImpl implements CodeCommentRPC {
// ------------------------------ FIELDS ------------------------------

  private CodeCommentService codeCommentService;

// --------------------- GETTER / SETTER METHODS ---------------------

  public void setCodeCommentService(CodeCommentService codeCommentService) {
    this.codeCommentService = codeCommentService;
  }

// ------------------------ INTERFACE METHODS ------------------------

// --------------------- Interface CodeCommentRPC ---------------------

  /**
   * Retrieve all comments registered for a file (with version, requested lines, url etc given by a code pointer).
   *
   * @param pointer file identifying pointer
   * @return a list of comments submitted for this file
   * @gwt.typeArgs <com.googlecode.continuity.plugin.codecomment.client.CodeComment>
   */
  public List getCommentsForFile(CodePointer pointer) {
    List<CodeComment> comments =  codeCommentService.getCommentsForFile(pointer);
    // eager fetch all properties except for the replies themselves
    for (CodeComment comment : comments) {
      comment.getReplies().size();
      comment.getSeverity().getName();
      comment.getAuthor().getUsername();
      comment.getLocation().getName();
      comment.getContent();
      comment.getCreationDate();
      comment.getRelatedComments().size();
    }
    return comments;
  }

  /**
   * Retrieves all comments registered for a file (with requested lines, url etc given by a code pointer and version
   * bounds given explicitely).
   *
   * @param pointer      file identifying pointer
   * @param firstVersion first version for which to retrieve comments (inclusive)
   * @param lastVersion  last version for which to retrieve comments (inclusive)
   * @return a list of comments submitted for this file
   * @gwt.typeArgs <com.googlecode.continuity.plugin.codecomment.client.CodeComment>
   */
  public List getCommentsForFile(CodePointer pointer, long firstVersion, long lastVersion) {
    List<CodeComment> comments =  codeCommentService.getCommentsForFile(pointer, firstVersion, lastVersion);
    // eager fetch all properties except for the replies themselves
    for (CodeComment comment : comments) {
      comment.getReplies().size();
      comment.getSeverity().getName();
      comment.getAuthor().getUsername();
      comment.getLocation().getName();
      comment.getContent();
      comment.getCreationDate();
      comment.getRelatedComments().size();
    }
    return comments;
  }

  public CodeComment addComment(CodeComment comment) {
    comment.setCreationDate(new Date(System.currentTimeMillis()));
    comment.setAuthor(
        ((SecurityUserToken) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUser());
    codeCommentService.storeComment(comment);
    return comment;
  }

  public Reply addReply(CodeComment comment, Reply reply) {
    reply.setCreationDate(new Date(System.currentTimeMillis()));
    reply.setAuthor(
        ((SecurityUserToken) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUser());
    comment.addReply(reply);
    codeCommentService.storeComment(comment);
    return reply;
  }
}
